package com.incross.dawin.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Iterator;

import org.apache.http.HttpResponse;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Element;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Build;

import com.incross.dawin.util.BKLog;

public class BKConnectionManager implements BKDataAsyncTask.OnTaskStateListener {
	private static final String TAG = "BKConnectionManager";
	
	// Error codes.
	public static final int NETWORK_DISCONNECTED = -100;
	public static final int DATA_PARSING_ERROR = -200;
	public static final int OTHER_CONNECTION_ERROR = -300;
	
	// request codes.
	public static final int REQUEST_SAMPLE = 11111110;
	public static final int REQUEST_SEND_TAG = 1000;
	public static final int REQUEST_AD_INFOS = 2000;
	
	public static final int TAG_START = 100;
	public static final int TAG_QUARTER = 110;
	public static final int TAG_HALF = 120;
	public static final int TAG_3QUARTER = 130;
	
	public static final String ICON_BASE_PATH = "http://112.169.59.42:8090/images/app/";
	
	public static final String FACEBOOK_ICON = "face.png";
	public static final String TWITTER_ICON = "twitter.png";
	public static final String ME2DAY_ICON = "me.png";
	public static final String SKIP_ICON = "skip.png";
	
	
	public static final int HTTP_POST = 0;
	public static final int HTTP_PUT  = 1;
	public static final int HTTP_GET  = 2;
	
	public static final String REQUEST_SUCCESS = "SUCCESS";
	public static final String REQUEST_FAIL = "FAILED";
	
	private Context mContext;
	private RequestStateListener mListener;
	
	private int mCurrentRequest = -1;
	private int mImpressionTag = -1;
	private String mRequestUrl;
	
	
	private BKDataAsyncTask mBKTask;
	
	public interface RequestStateListener {
		public abstract void onRequestFinished(int whichRequest, HttpResponse result, String extractString);
		public abstract void onRequestError(int whichRequest, int errorCode, String message);
	}
	
	public BKConnectionManager(Context con) {
		mContext = con;
	}
	
	public void sendRequest(int request, String url, JSONObject parameters) {
		if(!isNetworkConnected(mContext)) {
			mListener.onRequestError(request, NETWORK_DISCONNECTED, "Network is disconnected");
			return;
		}
		String param = null;
		if(parameters != null) {
			Iterator<String> keys = parameters.keys();
			ArrayList<String> paramKeys = new ArrayList<String>();
			while(keys.hasNext()) {
				paramKeys.add(keys.next());
			}
			
			param = getParameter(parameters, paramKeys);
		}
		
		if(param != null) {
			url = url + "?" + param;
		}
		
		mBKTask = new BKDataAsyncTask(mContext, this);
		mBKTask.setRequestCode(request);
		mBKTask.execute(url);
	}
	
	private String getParameter(JSONObject param, ArrayList<String> keys) {
		String result = "";
		try {
			for(int i = 0; i < keys.size(); i++) {
				if(i != 0) {
					result += "&";
				}
				String key = keys.get(i) + "=";
				String value = param.getString(keys.get(i));
				
				result += key += value;
			}
		} catch(JSONException e) {
			result = null;
		}
		
		return result;
	}
	
	public void setOnConnectionStateListener(RequestStateListener l) {
		mListener = l;
	}
	
	@Override
	public void onTaskFinished(int request, HttpResponse response, String extractString) {
		BKLog.d(extractString);
		
		String decodedResult = null;
		try {
			decodedResult = URLDecoder.decode(extractString, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		if(decodedResult != null) {
			if(mListener != null) {
				mListener.onRequestFinished(request, response, decodedResult);
			}
			
		} else {
			if(mListener != null) {
				mListener.onRequestError(request, DATA_PARSING_ERROR, "Decoding error");
			}
		}
		
	}
	
	@Override
	public void onHttpRequestError(int request, int resultCode, HttpResponse response) {
		if(mListener != null) {
			mListener.onRequestError(request, resultCode, "Request error");
		}
	}
	
	public static Element getXmlElementByHttpResponse(HttpResponse response) {
		Element result = null;
		InputStream is = null;
		String xmlStringResult = "";
		
		try {
			is = response.getEntity().getContent();
			BufferedReader reader = new BufferedReader(new InputStreamReader(is,"utf-8"), 8);
			
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
			is.close();
			xmlStringResult = sb.toString();
			
			
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		BKLog.e("parsing result : " + xmlStringResult);
		
		
		
		return result;
	}
	
	public static boolean isNetworkConnected(Context context) {
		ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        // 20131023 곰TV에서 특정기종(넥서스7 테블릿에서 Mobiletype으로 검색할 때 Network info가 null이 나오는 증상이 있어 NetworkInfo null check 구문 추가)
        boolean isWifiAvail = (ni != null?ni.isAvailable():false);
        boolean isWifiConn = (ni != null?ni.isConnected():false);
        ni = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        boolean isMobileAvail = (ni != null?ni.isAvailable():false);
        boolean isMobileConn = (ni != null?ni.isConnected():false);
 
        String status = "WiFi\nAvail = " + isWifiAvail + "\nConn = "
          + isWifiConn + "\nMobile\nAvail = " + isMobileAvail
          + "\nConn = " + isMobileConn + "\n";
        
        BKLog.e("isNetworkConnected");
 
        if (!isWifiConn && !isMobileConn) {
            return false;
        } else {
        	return true;
        }
        
        /*BKLog.e("isNetworkConnected");
		
		ConnectivityManager connectManager = null;
		if(connectManager == null) {
			connectManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		}
		if(connectManager == null) {
			BKLog.e("1");
			return false;
		}
		if(connectManager.getActiveNetworkInfo()!=null) {
			NetworkInfo activeNetwork = connectManager.getActiveNetworkInfo();
			if(activeNetwork == null) {
				BKLog.e("2");
				return false;
			}
			switch(activeNetwork.getType()) {
				case ConnectivityManager.TYPE_WIMAX:
					BKLog.e("3");
					return true;

				case ConnectivityManager.TYPE_MOBILE:
					BKLog.e("4");
	                return true;

				case ConnectivityManager.TYPE_WIFI:
					BKLog.e("5");
	                return false;
			}

		}else{
			BKLog.e("6");
			return false;
		}
		BKLog.e("7");
		return false;*/

	}
	
	public static boolean getNetworkStatus(Context context) {
		ConnectivityManager cm = (ConnectivityManager) context.getSystemService("connectivity");
		NetworkInfo netInfo_mobile = cm.getNetworkInfo(0);
		
		WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

		if ((netInfo_mobile == null) && !manager.isWifiEnabled()) {
			return false;
		}

		return (netInfo_mobile.getState() == NetworkInfo.State.CONNECTED) || (isWiMAXNetworkConnected(cm)) || manager.isWifiEnabled();
	}

	public static boolean get3GMobileNetworkStatus(Context context) {
		 NetworkInfo info = (NetworkInfo) ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
		 if(info == null || !info.isConnected()) {
			 return false;
		 }
		 
		 if(info.isRoaming()) {
			 return false;
		 }
		 
		 return true;

	}

	private static boolean isWiMAXNetworkConnected(
			ConnectivityManager connectivityManager) {
		if (Build.VERSION.SDK_INT >= 8) {
			NetworkInfo wimaxNetwork = connectivityManager.getNetworkInfo(6);
			if ((wimaxNetwork != null) && (wimaxNetwork.isConnected()))
				return true;
		}

		return false;
	}
	
}